package com.quectel.taskserver.mock.job;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.quectel.business.common.websocket.WebSocketComponent;
import com.quectel.business.common.websocket.send.SendMsgType;
import com.quectel.constant.core.device.DeviceCategoryCodeConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.core.module.device.dto.DeviceDto;
import com.quectel.core.module.device.service.DeviceService;
import com.quectel.core.module.entranceguard.dto.mongo.MongoPersonAccessRecordDto;
import com.quectel.core.module.entranceguard.service.mongo.MongoPersonAccessRecordService;
import com.quectel.core.module.household.dto.HouseholdDto;
import com.quectel.core.module.household.service.HouseholdService;
import com.quectel.core.module.village.dto.VillageDto;
import com.quectel.core.module.village.service.VillageService;
import com.quectel.taskserver.mock.MockLimit;
import com.quectel.util.common.JacksonUtils;
import com.quectel.util.kit.Snowflake;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.shardingsphere.elasticjob.api.ShardingContext;
import org.apache.shardingsphere.elasticjob.simple.job.SimpleJob;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.security.SecureRandom;
import java.util.*;

/**
 * @author bob
 * @email bob.yu@quectel.com
 * @date 2022/4/13 上午11:05
 * 模拟生成人行进出记录
 */
@Component
public class YsxqPersonRecordGenerateMock implements SimpleJob {

    @DubboReference
    private HouseholdService householdService;
    @DubboReference
    private VillageService villageService;
    @DubboReference
    private DeviceService deviceService;
    @DubboReference
    private MongoPersonAccessRecordService personAccessRecordService;
    @Autowired
    private WebSocketComponent webSocketComponent;

    @Override
    public void execute(ShardingContext shardingContext) {
        generatePersonRecord();
    }

    public void generatePersonRecord() {
        if (!MockLimit.enableMock() || MockLimit.mockVillageCodes() == null) {
            return;
        }
        for (String villageCode : MockLimit.mockVillageCodes()) {
            VillageDto villageDto = villageService.selectByCode(villageCode);
            if (villageDto == null) {
                continue;
            }

            List<DeviceDto> result = new ArrayList<>();
            int pageNo = 0;
            Map<String, Object> queryDevicesMap = new HashMap<>();
            queryDevicesMap.put(LambdaUtil.getFieldName(DeviceDto::getVillageId), villageDto.getId());
            queryDevicesMap.put("limit", 1000);
            while (true) {
                queryDevicesMap.put("offset", pageNo++ * 1000);
                queryDevicesMap.put("deviceCategoryCode", DeviceCategoryCodeConstants.INTELLIGENT_ENTRANCE_GUARD);
                List<DeviceDto> list = deviceService.queryList(queryDevicesMap);
                if (org.apache.commons.collections4.CollectionUtils.isEmpty(list)) {
                    break;
                }
                result.addAll(list);
                if (list.size() < 1000) {
                    break;
                }
            }

            List<HouseholdDto> householdDtos = new ArrayList<>();

            householdDtos.add(householdService.selectById(566673774494097408L));
            householdDtos.add(householdService.selectById(566673776545112064L));
            householdDtos.add(householdService.selectById(566673778684207104L));
            householdDtos.add(householdService.selectById(566673781804769280L));
            householdDtos.add(householdService.selectById(566673783042088960L));
            householdDtos.add(householdService.selectById(566673784040333312L));

            for (int j = 0; j < householdDtos.size(); j++) {
                SecureRandom secureRandom = new SecureRandom();
                int i = secureRandom.nextInt(result.size());
                HouseholdDto householdDto = householdDtos.get(j);
                MongoPersonAccessRecordDto personAccessRecordDto = new MongoPersonAccessRecordDto();
                personAccessRecordDto.setId(Snowflake.nextId());
                personAccessRecordDto.setTenantId(householdDto.getTenantId());
                personAccessRecordDto.setVillageId(householdDto.getVillageId());
                personAccessRecordDto.setDeviceId(result.get(i).getId());
                personAccessRecordDto.setDeviceName(result.get(i).getName());
                personAccessRecordDto.setPersonType(householdDto.getType());
                personAccessRecordDto.setPersonId(householdDto.getId());
                personAccessRecordDto.setPersonName(householdDto.getName());
                personAccessRecordDto.setPersonMobile(householdDto.getMobile());
                if (StringUtils.isNotBlank(householdDto.getTags()) && JSONUtil.isTypeJSONObject(householdDto.getTags())) {
                    HashMap<String, Object> parse = JacksonUtils.parse(householdDto.getTags(), new TypeReference<HashMap<String, Object>>(){});
                    if (parse != null && parse.size() > 0) {
                        personAccessRecordDto.setFocus(SystemConstants.YES);
                        webSocketComponent.sendMsgToCmsApi(householdDto.getVillageId()
                                , SendMsgType.FOCUS.getMsgTypeFlag()
                                , SendMsgType.FOCUS.getTitle()
                                , SendMsgType.FOCUS.getContentFunc().apply(new String[]{householdDto.getName(), DateUtil.now(), result.get(i).getName()})
                                , null);
                    }
                }
                personAccessRecordDto.setAccessMode((byte) 6);
                personAccessRecordDto.setOutOrIn((byte) RandomUtil.randomInt(1, 3));
                String[] strings = new String[1];
                strings[0] = householdDto.getFaceImg();
                personAccessRecordDto.setSnapImages(JacksonUtils.toJsonString(strings));
                personAccessRecordDto.setEventTime(DateUtil.offsetMinute(new Date(), -RandomUtil.randomInt(20)));
                personAccessRecordDto.setAccessTime(DateUtil.offsetMinute(new Date(), -RandomUtil.randomInt(20)));
                personAccessRecordService.save(personAccessRecordDto);
            }
        }
    }
}
